package com.xqb.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.xqb.common.exception.ServiceException;
import com.xqb.common.utils.SecurityUtils;
import com.xqb.common.utils.bean.BeanUtils;
import com.xqb.modules.domain.dto.ExaQuestionDto;
import com.xqb.modules.domain.po.ExaQuestion;
import com.xqb.modules.domain.po.ExaQuestionBiz;
import com.xqb.modules.domain.po.ExaQuestionDetail;
import com.xqb.modules.domain.po.LesCategory;
import com.xqb.modules.domain.vo.ExamQuestionDetailVo;
import com.xqb.modules.domain.vo.ExamQuestionVo;
import com.xqb.modules.mapper.ExaQuestionBizMapper;
import com.xqb.modules.mapper.ExaQuestionDetailMapper;
import com.xqb.modules.mapper.ExaQuestionMapper;
import com.xqb.modules.mapper.LesCategoryMapper;
import com.xqb.modules.service.IExaQuestionService;
import com.xqb.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 题目Service业务层处理
 *
 * @author xqb
 * @date 2024-10-14
 */
@Service
public class ExaQuestionServiceImpl implements IExaQuestionService {
    @Autowired
    private ExaQuestionMapper exaQuestionMapper;
    @Autowired
    private ExaQuestionBizMapper exaQuestionBizMapper;
    @Autowired
    private ExaQuestionDetailMapper exaQuestionDetailMapper;
    @Autowired
    private LesCategoryMapper lesCategoryMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询题目
     *
     * @param id 题目主键
     * @return 题目
     */
    @Override
    public ExaQuestion selectExaQuestionById(Long id) {
        return exaQuestionMapper.selectExaQuestionById(id);
    }

    /**
     * 查询题目列表
     *
     * @param exaQuestion 题目
     * @return 题目
     */
    @Override
    public List<ExaQuestion> selectExaQuestionList(ExaQuestion exaQuestion) {
        return exaQuestionMapper.selectExaQuestionList(exaQuestion);
    }

    /**
     * 新增题目
     *
     * @param exaQuestion 题目
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertExaQuestion(ExaQuestionDto exaQuestion) {
        int row = 0;
        if (exaQuestion.getInsId() == null) {
            exaQuestion.setInsId(SecurityUtils.getLoginUser().getUser().getInsId());
        }
        ExaQuestion newExaQuestion = new ExaQuestion();
        BeanUtils.copyProperties(exaQuestion, newExaQuestion);
        row += exaQuestionMapper.insert(newExaQuestion);
        ExaQuestionDetail newExaQuestionDetail = new ExaQuestionDetail();
        BeanUtils.copyProperties(exaQuestion, newExaQuestionDetail);
        newExaQuestionDetail.setId(newExaQuestion.getId());
        row += exaQuestionDetailMapper.insert(newExaQuestionDetail);
        return row;
    }

    /**
     * 修改题目
     *
     * @param exaQuestion 题目
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateExaQuestion(ExaQuestionDto exaQuestion) {
        int row = 0;
        ExaQuestion newExaQuestion = new ExaQuestion();
        BeanUtils.copyProperties(exaQuestion, newExaQuestion);
        ExaQuestionDetail newExaQuestionDetail = new ExaQuestionDetail();
        BeanUtils.copyProperties(exaQuestion, newExaQuestionDetail);
        row += exaQuestionDetailMapper.updateById(newExaQuestionDetail);
        row += exaQuestionMapper.updateById(newExaQuestion);
        return row;
    }

    /**
     * 批量删除题目
     *
     * @param ids 需要删除的题目主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteExaQuestionByIds(Long[] ids) {
        List<Long> newIds = java.util.Arrays.asList(ids);
        List<ExaQuestionBiz> bizList = exaQuestionBizMapper.selectList(new LambdaQueryWrapper<ExaQuestionBiz>().in(ExaQuestionBiz::getQuestionId, newIds));
        if (bizList.size() > 0) {
            throw new ServiceException("该题目已被使用，不能删除");
        }
        int row = 0;
        row += exaQuestionDetailMapper.deleteBatchIds(newIds);
        row += exaQuestionMapper.deleteBatchIds(newIds);
        return row;
    }

    /**
     * 删除题目信息
     *
     * @param id 题目主键
     * @return 结果
     */
    @Override
    public int deleteExaQuestionById(Long id) {
        List<ExaQuestionBiz> bizList = exaQuestionBizMapper.selectList(new LambdaQueryWrapper<ExaQuestionBiz>().eq(ExaQuestionBiz::getQuestionId, id));
        if (bizList.size() > 0) {
            throw new ServiceException("该题目已被使用，不能删除");
        }
        int row = 0;
        row += exaQuestionDetailMapper.deleteById(id);
        row += exaQuestionMapper.deleteById(id);
        return row;
    }

    /**
     * 查询业务相关题目
     *
     * @param id 业务主键
     * @return 题目列表
     */
    @Override
    public List<ExamQuestionVo> questionList(Long id) {
        LambdaQueryWrapper<ExaQuestionBiz> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ExaQuestionBiz::getBizId, id);
        List<Long> qIds = exaQuestionBizMapper.selectList(queryWrapper).stream().map(ExaQuestionBiz::getQuestionId).collect(Collectors.toList());
        if (qIds.size() == 0) {
            return new ArrayList<>();
        }
        return exaQuestionMapper.selectQuestionList(qIds);
    }

    /**
     * 获取题目详情列表。
     *
     * @param exaQuestion 题目查询条件
     * @return 题目详情列表
     */
    @Override
    public List<ExamQuestionDetailVo> getExaQuestionList(ExaQuestion exaQuestion) {
        // 从数据库中查询题目详情列表
        List<ExamQuestionDetailVo> examQuestionDetailVoList = exaQuestionMapper.selectExaQuestionDetailVoList(exaQuestion);

        // 如果查询结果为空，则直接返回空列表
        if (examQuestionDetailVoList == null || examQuestionDetailVoList.isEmpty()) {
            return Collections.emptyList();
        }

        // 提取所有一级分类ID
        Set<Long> category1Ids = examQuestionDetailVoList.stream()
                // 提取每个题目详情对象中的一级分类ID
                .map(ExamQuestionDetailVo::getCateId1)
                // 将所有一级分类ID收集到Set集合中，去除重复元素
                .collect(Collectors.toSet());

        // 提取所有二级分类ID
        Set<Long> category2Ids = examQuestionDetailVoList.stream()
                // 提取每个题目详情对象中的二级分类ID
                .map(ExamQuestionDetailVo::getCateId2)
                // 将所有二级分类ID收集到Set集合中，去除重复元素
                .collect(Collectors.toSet());

        // 提取所有三级分类ID
        Set<Long> category3Ids = examQuestionDetailVoList.stream()
                // 提取每个题目详情对象中的三级分类ID
                .map(ExamQuestionDetailVo::getCateId3)
                // 将所有三级分类ID收集到Set集合中，去除重复元素
                .collect(Collectors.toSet());

        // 合并所有分类ID到一个Set集合中
        Set<Long> allCategoryIds = new HashSet<>(category1Ids);
        allCategoryIds.addAll(category2Ids);
        allCategoryIds.addAll(category3Ids);
        // 根据分类ID查询分类信息，并存储到Map中
        Map<Long, String> categoryMap = !allCategoryIds.isEmpty() ? queryCategoriesByIds(new ArrayList<>(allCategoryIds)) : Collections.emptyMap();

        // 遍历题目详情列表，将用户信息和分类信息填充到每个题目详情对象中
        examQuestionDetailVoList.forEach(vo -> {
            // 设置一级分类名称
            vo.setCateName1(categoryMap.getOrDefault(vo.getCateId1(), null));
            // 设置二级分类名称
            vo.setCateName2(categoryMap.getOrDefault(vo.getCateId2(), null));
            // 设置三级分类名称
            vo.setCateName3(categoryMap.getOrDefault(vo.getCateId3(), null));
        });

        //返回填充了用户信息和分类信息的题目详情列表
        return examQuestionDetailVoList;
    }

    /**
     * 根据分类ID列表查询分类信息，并返回分类ID和分类名称对应的Map集合
     *
     * @param categoryIds 分类ID列表
     * @return 分类ID和分类名称对应的Map集合，如果传入的分类ID列表为空，则返回空的Map集合
     */
    private Map<Long, String> queryCategoriesByIds(List<Long> categoryIds) {
        // 如果传入的分类ID列表为空，则直接返回一个空的Map
        if (categoryIds.isEmpty()) {
            // 如果分类ID列表为空，则返回一个空的Map
            return Collections.emptyMap();
        }

        // 创建一个LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<LesCategory> categoryQueryWrapper = new LambdaQueryWrapper<>();

        // 设置查询条件：分类ID在传入的分类ID列表中
        categoryQueryWrapper.in(LesCategory::getId, categoryIds);

        // 设置查询字段：只查询分类ID和分类名称
        categoryQueryWrapper.select(LesCategory::getId, LesCategory::getName);

        // 执行查询操作，获取满足条件的分类列表
        List<LesCategory> categoryList = lesCategoryMapper.selectList(categoryQueryWrapper);

        // 将查询结果转换为Map集合，其中Key为分类ID，Value为分类名称
        return categoryList.stream().collect(Collectors.toMap(LesCategory::getId, LesCategory::getName));
    }

    @Override
    public String importByExcel(List<ExaQuestionDto> exaQuestionDtos) {
        if (CollectionUtils.isEmpty(exaQuestionDtos)) {
            throw new ServiceException("导入题目数据不能为空");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (ExaQuestionDto question : exaQuestionDtos) {
            try {
//                exaQuestionMapper.insert(question);
                successNum++;
                successMsg.append("<br/>").append(successNum).append("、题目 ").append(question.getName()).append(" 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、题目 " + question.getName() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        if (successNum > 0) {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();

    }
}
